﻿using System;
using Assignment_2.Entities.Components;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Assignment_2.Entities
{
    class Ocean : Entity
    {
        public Texture2D Heightmap { get; set; }
        public Texture2D WorldTex { get; set; }
        
        private const float Radius = 100.0f;
        
        public Ocean(GraphicsDevice device, Texture2D heightmap, Texture2D worldTex)
        {
            Heightmap = heightmap;
            WorldTex = worldTex;

            Initialize(device);
        }

        public void Initialize(GraphicsDevice device)
        {
            DrawComponents.Add("OceanMesh", new VptComponent(this, device, InitializeVertices(), InitializeIndices()) { Texture = WorldTex});
        }

        private VertexPositionTexture[] InitializeVertices()
        {
            var vertices = new VertexPositionTexture[Heightmap.Width * Heightmap.Height + Heightmap.Height];

            for (var x = 0; x < Heightmap.Width; x++)
            {
                for (var y = 0; y < Heightmap.Height; y++)
                {
                    var ringradius = (float)(Radius * Math.Sin(-y * Math.PI / Heightmap.Height)) + (float)212 / 50;

                    var xyz = new Vector3(
                            (float)(Math.Cos((Heightmap.Width - x) * Math.PI * 2.0f / Heightmap.Width) * ringradius),
                            (float)(Math.Cos(y * Math.PI / Heightmap.Height) * Radius),
                            (float)(Math.Sin((Heightmap.Width - x) * Math.PI * 2.0f / Heightmap.Width) * ringradius));

                    vertices[x + y * Heightmap.Width] = new VertexPositionTexture(xyz, new Vector2(0, 0));
                }
            }


            for (var y = 0; y < Heightmap.Height; y++)
            {
                vertices[Heightmap.Width + 1 + y * Heightmap.Width] = vertices[0 + y * Heightmap.Width];
                vertices[Heightmap.Width + 1 + y * Heightmap.Width].TextureCoordinate = new Vector2((float)(Heightmap.Width + 1) / (Heightmap.Width), (float)(y) / (Heightmap.Height));
            }

            for (var x = 0; x < Heightmap.Width + 1; x++)
            {
                for (var y = 0; y < Heightmap.Height; y++)
                {
                    vertices[x + y * Heightmap.Width].TextureCoordinate = new Vector2((float)(x) / (Heightmap.Width), (float)(y) / (Heightmap.Height));
                }
            }

            return vertices;
        }

        private int[] InitializeIndices()
        {
            var indices = new int[6 * (Heightmap.Width - 1) * (Heightmap.Height - 1) + (Heightmap.Height - 1) * 6];
            var number = 0;

            for (var y = 0; y < Heightmap.Height - 1; y++)
            {
                for (var x = 0; x < Heightmap.Width; x++)
                {
                    indices[number] = x + (y + 1) * Heightmap.Width;      // up left
                    indices[number + 1] = x + y * Heightmap.Width;            // down left
                    indices[number + 2] = x + y * Heightmap.Width + 1;        // down right
                    indices[number + 3] = x + (y + 1) * Heightmap.Width;      // up left
                    indices[number + 4] = x + y * Heightmap.Width + 1;        // down right
                    indices[number + 5] = x + (y + 1) * Heightmap.Width + 1;  // up right
                    number += 6;
                }
            }

            return indices;
        }

    }
    
}
